package com.zhrj.exam.common;

import org.springframework.validation.BindException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * 全局异常处理器
 */
@RestControllerAdvice("com.zhrj.exam.controller")
public class GlobalExceptionHandler {

    // ------------------------- 处理自定义业务异常 -------------------------
    @ExceptionHandler(BusinessException.class)
    public Result<?> handleBusinessException(BusinessException e) {
        return Result.fail(e.getCode(), e.getMessage());
    }

    // ------------------------- 处理参数校验异常 -------------------------
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        ObjectError error = e.getBindingResult().getAllErrors().get(0);
        String message = String.format("参数校验失败: %s", error.getDefaultMessage());
        return Result.fail(400, message);
    }

    @ExceptionHandler(BindException.class)
    public Result<?> handleBindException(BindException e) {
        ObjectError error = e.getBindingResult().getAllErrors().get(0);
        String message = String.format("参数绑定失败: %s", error.getDefaultMessage());
        return Result.fail(400, message);
    }

    // ------------------------- 处理系统级异常 -------------------------
//    @ExceptionHandler(Exception.class)
//    public Result<?> handleException(Exception e) {
//        // 生产环境建议隐藏详细错误信息
//        String message = "系统繁忙，请稍后再试";
//        // 开发环境可返回详细错误
//        // String message = e.getMessage();
//        return Result.error(message);
//    }

    // ------------------------- 自定义业务异常类 -------------------------
    public static class BusinessException extends RuntimeException {
        private final Integer code;

        public BusinessException(Integer code, String message) {
            super(message);
            this.code = code;
        }

        public Integer getCode() {
            return code;
        }
    }
}